<script setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'

// 引入公共上传组件
import uploadImage from '@/components/upload-image.vue'

import { getFieldsApi, readTableSearchApi, saveTableSearchApi, getSourceListApi } from '@/service/db.js'

const emit = defineEmits(['fetchList'])

const drawerTitle = ref('设置表结构')

const fieldList = ref([])

// 数据源列表
const sourceList = ref([])

// 获取数据源列表
const getSourceList = () => {
  getSourceListApi().then(res => {
    sourceList.value = res.data
  })
}


// 从接口获取数据
const getFields = (table) => {
  getFieldsApi({ table }).then(res => {
    fieldList.value = res.data
  })
}

// 表单项类型
const formItemTypes = [
  { label: '输入框', value: 'input' },
  { label: '下拉框', value: 'select' },
  { label: '单选框', value: 'radio' },
  { label: '日期选择', value: 'date' },
  { label: '开关', value: 'switch' },
]

const formItems = reactive([]);
const field = {
  Field: '',
  Type: '',
  Title: '',
  Default: '',
  FormItemType: 'input',
  Placeholder: '',
  Options: [],
  DataSource: '',
  DataType: 'options'
}

const activeField = reactive({ ...field })

// 左侧字段添加到表单
const appendToForm = (row) => {
  // 如果已经存在
  if (formItems.find(item => item.Field === row.Field)) {
    ElMessage.warning('字段已经存在')
    return
  }

  row.Title = row.Comment
  let formItem = Object.assign({}, { ...field }, row)

  formItems.push(formItem)

  // 设置表单项
  setFormItem(formItem)
}

// 设置表单项
const setFormItem = (data) => {
  let item = JSON.parse(JSON.stringify(data));
  activeField.Field = item.Field
  activeField.Title = item.Title
  activeField.Default = item.Default
  activeField.FormItemType = item.FormItemType
  activeField.Placeholder = item.Placeholder
  activeField.Options = item.Options || []
  activeField.DataSource = item.DataSource
  activeField.DataType = item.DataType
}

// 上移
const moveUp = (item) => {
  let index = formItems.indexOf(item)
  // 如果是第一个
  if (index === 0) {
    // 提示已经是第一个
    ElMessage.warning('已经是第一个了')
    return
  }

  // 如果不是第一个
  if (index > 0) {
    let temp = formItems[index - 1]
    formItems[index - 1] = item
    formItems[index] = temp
  }
}

// 下移
const moveDown = (item) => {
  let index = formItems.indexOf(item)
  // 如果是最后一个
  if (index === formItems.length - 1) {
    // 提示已经是最后一个
    ElMessage.warning('已经是最后一个了')
    return
  }

  if (index < formItems.length - 1) {
    let temp = formItems[index + 1]
    formItems[index + 1] = item
    formItems[index] = temp
  }
}

// 同步字段配置
const syncFieldConfig = () => {
  console.log(activeField)
  let index = formItems.findIndex(item => item.Field === activeField.Field)
  formItems[index] = Object.assign({}, formItems[index], { ...activeField })
}

// 移除表单项
const removeFormItem = (item) => {
  let index = formItems.findIndex(i => i.Field === item.Field)
  formItems.splice(index, 1)
}

// 添加选项
const appendOptions = () => {
  activeField.Options.push({ label: '', value: '' })
}

// 移除选项
const removeOptions = (item) => {
  let index = activeField.Options.indexOf(item)
  activeField.Options.splice(index, 1)
}


// 同步选项到字段
const asyncOptionsToField = () => {
  let index = formItems.findIndex(item => item.Field === activeField.Field)
  formItems[index].Options = activeField.Options
  // 提示
  ElMessage.success('同步成功')
}

const table = ref('')
const dialogVisible = ref(false)
const openDrawer = (row) => {

  table.value = row.name;
  drawerTitle.value = `设置表结构 - ${table.value}`
  dialogVisible.value = true;

  // 初始化formItems
  formItems.splice(0, formItems.length)
  getFields(table.value)
  getSourceList()

  // 读取表单配置
  readTableSearchApi({ table: table.value }).then(({ code, data }) => {
    if (code === 200) {
      formItems.splice(0, formItems.length, ...data)
    }
  })
}
const closeDrawer = () => {
  dialogVisible.value = false;
}

// 保存表单配置
const saveTableForm = () => {
  if (!formItems.length) {
    ElMessage.warning('请添加表单项')
    return
  }

  saveTableSearchApi({ table: table.value, items: formItems }).then(({ code, msg }) => {
    if (code === 200) {
      ElMessage.success(msg)
      // 关闭抽屉
      closeDrawer()
      // 刷新列表
      emit('fetchList')
    } else {
      ElMessage.error(msg)
    }
  })
}

defineExpose({
  openDrawer,
  closeDrawer
});

</script>

<template>
  <el-drawer :title="drawerTitle" v-model="dialogVisible" size="100%">
    <div class="container">
      <el-aside class="field-list">
        <el-table :data="fieldList" border style="width: 100%">
          <el-table-column prop="Field" label="字段">
            <template #default="{ row }">
              <div class="flex">
                <div class="left">{{ row.Field }}</div>
                <div class="right">{{ row.Type }}</div>
              </div>
              <div class="flex tip">
                <div class="left">{{ row.Comment }}</div>
                <div class="right btn">
                  <el-icon @click="appendToForm(row)">
                    <Plus></Plus>
                  </el-icon>
                </div>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-aside>
      <div class="form">
        <el-form ef="ruleForm" label-width="100px" label-position="top">
          <el-form-item v-for="item in formItems" :key="item.Field" :label="item.Title" :prop="item.Field">
            <div class="form-item-group">
              <div class="form-item">
                <el-input v-if="item.FormItemType === 'input'" v-model="item.Default"
                  :placeholder="item.Placeholder"></el-input>
                <el-select v-else-if="item.FormItemType === 'select'" v-model="item.Default"
                  :placeholder="item.Placeholder" clearable filterable>
                  <el-option v-for="option in item.Options" :key="option.value" :label="option.label"
                    :value="option.value"></el-option>
                </el-select>
                <el-radio-group v-else-if="item.FormItemType === 'radio'" v-model="item.Default">
                  <el-radio v-for="option in item.Options" :key="option.value" :label="option.value">{{
                    option.label
                  }}
                  </el-radio>
                </el-radio-group>
                <el-checkbox-group v-else-if="item.FormItemType === 'checkbox'" v-model="item.Default">
                  <el-checkbox v-for="option in item.Options" :key="option.value" :label="option.value">{{
                    option.label
                  }}
                  </el-checkbox>
                </el-checkbox-group>
                <el-date-picker v-else-if="item.FormItemType === 'date'" v-model="item.Default" type="date"
                  value-format="YYYY-MM-DD" :placeholder="item.Placeholder"></el-date-picker>
                <el-input v-else-if="item.FormItemType === 'textarea'" type="textarea" v-model="item.Default"
                  :placeholder="item.Placeholder"></el-input>
                <el-switch v-else-if="item.FormItemType === 'switch'" v-model="item.Default"></el-switch>
                <el-slider v-else-if="item.FormItemType === 'slider'" v-model="item.Default"></el-slider>
                <upload-image v-else-if="item.FormItemType === 'upload'" v-model="item.Default"></upload-image>
              </div>
              <div class="btn-group">
                <el-button type="primary" icon="Setting" circle @click="setFormItem(item)" />
                <el-button type="primary" icon="ArrowUp" circle @click="moveUp(item)" />
                <el-button type="primary" icon="ArrowDown" circle @click="moveDown(item)" />
                <el-button type="danger" icon="Minus" circle @click="removeFormItem(item)" />
              </div>
            </div>
          </el-form-item>

          <el-form-item>
            <el-button type="primary" @click="saveTableForm">保存配置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <el-aside class="field-config">
        <el-form :model="activeField" label-position="top">
          <el-form-item label="字段标题">
            <el-input v-model="activeField.Title" @input="syncFieldConfig"></el-input>
          </el-form-item>
          <el-form-item label="字段名">
            <el-input v-model="activeField.Field" disabled></el-input>
          </el-form-item>
          <el-form-item label="表单类型">
            <el-select v-model="activeField.FormItemType" @change="syncFieldConfig">
              <el-option v-for="item in formItemTypes" :key="item.value" :label="item.label"
                :value="item.value"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="['select', 'radio', 'checkbox'].includes(activeField.FormItemType)" label="选项">
            <div class="multiple-box">
              <div class="switch-box">
                <el-switch v-model="activeField.DataType" @change="syncFieldConfig" active-value="DataSource"
                  active-text="数据源" inactive-value="Options" inactive-text="选项"></el-switch>
              </div>
              <div class="source-list" v-if="activeField.DataType === 'DataSource'">
                <el-select v-model="activeField.DataSource" placeholder="请选择数据源" clearable filterable
                  @change="syncFieldConfig">
                  <el-option v-for="item in sourceList" :key="item.table" :label="item.title"
                    :value="item.table"></el-option>
                </el-select>
              </div>
              <div v-else class="option-list">
                <div class="options-toolbar">
                  <el-button type="primary" @click="appendOptions">添加</el-button>
                  <el-button type="primary" @click="asyncOptionsToField">应用</el-button>
                </div>
                <div class="option-item" v-for="item in activeField.Options">
                  <el-input v-model="item.label" placeholder="显示文本"></el-input>
                  <el-input v-model="item.value" placeholder="入库值" class="space"></el-input>
                  <div class="btn-group">
                    <el-button type="danger" icon="Minus" circle @click="removeOptions" />
                  </div>
                </div>
              </div>
            </div>
          </el-form-item>
          <el-form-item label="默认值">
            <el-input v-model="activeField.Default" @input="syncFieldConfig"></el-input>
          </el-form-item>
          <el-form-item label="提示信息">
            <el-input v-model="activeField.Placeholder" @input="syncFieldConfig"></el-input>
          </el-form-item>
        </el-form>
      </el-aside>
    </div>
  </el-drawer>
</template>

<style scoped lang="less">
.flex {
  display: flex;
  justify-content: space-between;

  .btn {
    cursor: pointer;
  }
}

.flex.tip {
  color: #409eff;
  font-weight: bold;
}

.container {
  display: flex;
  justify-content: space-between;
  // 高度撑满
  height: 100%;
  overflow: hidden;

  .form {
    flex: 1;
    padding: 0 12px;

    .form-item-group {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100%;
      border-bottom: 1px solid #ebeef5;
      padding-bottom: 12px;

      .form-item {
        flex: 1;
      }

      .btn-group {
        width: fit-content;
        padding-left: 12px;
        margin-top: -3px;
      }
    }
  }

  .field-config {
    border-left: 1px solid #ebeef5;
    padding-left: 12px;

    .switch-box {
      padding: 8px 0;
    }

    .option-list {
      .options-toolbar {
        padding: 8px 0;
      }

      .option-item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 8px;

        .space {
          margin: 0 8px;
        }

        .btn-group {
          width: 20%;
          padding-left: 12px;
          margin-top: -3px;
        }
      }
    }
  }
}
</style>
